/***************************************************************
 *  Copyright (c) 2007 by GroupMe! Team (www.groupme.net)
 *  All rights reserved.
 *
 *  This file is part of the GroupMe! Project. Source code of 
 *  this project is closed and redistribution of this code is
 *  prohibited. 
 *  
 *  Contact: http://www.groupme.net
 *
 *  This copyright notice MUST APPEAR in all copies of the file!
 ***************************************************************/
package net.groupme.similarityComputer;

import java.util.Iterator;

import net.groupme.model.Group;
import net.groupme.model.Resource;
import net.groupme.model.Tag;

/**
 * created on feb 20, 2000
 * 
 * This class calculates a score for two different Groups depending on their
 * equality
 * 
 * @author Patrick Siehndel <a
 *         href="mailto:patrick.siehndel@gmx.de">patrick.siehndel@gmx.de</a>
 * @author last edited by: $Author: fabian $
 * 
 * @version $Revision: 1.3 $ $Date: 2008-02-28 20:54:44 $
 */

public class SimCom implements SimilarityComputer {

	private Group group1, group2;

	private int ScoreForSameResourceInGroup = 800;
	private int ScoreForSameTagOfResource = 100;
	private int ScoreForSameTagOfGroup = 100;
	private int ScoreForSameTagOfDifferentResource = 30;
	private double groupTagMultiplikationFactor = 1.4;
	private double resourceTagMultiplikationFactor = 1.5;
	private double resourceMultiplikationFactor = 1.3;
	private double resourceTagDiffernetMultiplikationFactor = 1.1;

	public SimCom(Group group1, Group group2) {
		this.group1 = group1;
		this.group2 = group2;
	}

	/* (non-Javadoc)
	 * @see net.groupme.similarityComputer.SimilarityComputer#getOverallScore()
	 */
	public int getOverallScore() {
		return getScoreForResources() + getScoreForTags();
	}

	/**
	 * Returns a Integer representing the Score (counting the same resources in
	 * the two Groups)
	 * 
	 * @return the score only for same resources
	 */
	public int getScoreForResources() {

		int score = 0;
		double resourceMultiplicator = 1;

		Iterator<Resource> groupIter1 = group1.getResources().iterator();

		while (groupIter1.hasNext()) {
			Iterator<Resource> groupIter2 = group2.getResources().iterator();
			Resource resource1 = groupIter1.next();
			while (groupIter2.hasNext()) {
				Resource resource2 = groupIter2.next();

				if (resource1.getURI().equals(resource2.getURI())) {
					score += ScoreForSameResourceInGroup
							* resourceMultiplicator;
					resourceMultiplicator = resourceMultiplicator
							* resourceMultiplikationFactor;
				}
			}
		}
		return score;
	}

	/**
	 * Returns a Integer representing the Score (counting the same tags given to
	 * the same resources)
	 * 
	 * @return the score only for the tags
	 */
	public int getScoreForTags() {
		int score = 0;
		double tagMultiplicator = 1;
		double tagMultiplicatorDifferent = 1;
		int numberOfResourcesMultiplicator = 1+((group1.getResources().size() +  group2.getResources().size())/15);
		
		Iterator<Resource> groupIter1 = group1.getResources().iterator();

		
		while (groupIter1.hasNext()) {
			Iterator<Resource> groupIter2 = group2.getResources().iterator();
			Resource resource1 = groupIter1.next();
			while (groupIter2.hasNext()) {
				Resource resource2 = groupIter2.next();

				if (resource1.getURI().equals(resource2.getURI())) {
					tagMultiplicator = 1;
					Iterator<Tag> tagIter1 = resource1.getTags().iterator();
					while (tagIter1.hasNext()) {
						Iterator<Tag> tagIter2 = resource2.getTags().iterator();
						String Keyword1 = tagIter1.next().getKeyword();
						while (tagIter2.hasNext()) {
							if (Keyword1.equals(tagIter2.next().getKeyword())) {
								score += ScoreForSameTagOfResource
										* tagMultiplicator * numberOfResourcesMultiplicator;
								tagMultiplicator = tagMultiplicator
										* resourceTagMultiplikationFactor;
							}
						}
					}
				} else {
					tagMultiplicator = tagMultiplicator
							* resourceTagMultiplikationFactor;

					tagMultiplicatorDifferent = 1;
					Iterator<Tag> tagIter1 = resource1.getTags().iterator();
					while (tagIter1.hasNext()) {
						Iterator<Tag> tagIter2 = resource2.getTags().iterator();
						String Keyword1 = tagIter1.next().getKeyword();
						while (tagIter2.hasNext()) {
							if (Keyword1.equals(tagIter2.next().getKeyword())) {
								score += ScoreForSameTagOfDifferentResource
										* tagMultiplicatorDifferent;
								tagMultiplicatorDifferent = tagMultiplicatorDifferent
										* resourceTagDiffernetMultiplikationFactor;
							}
						}
					}

				}

			}
		}

		Iterator<Tag> groupTagIter1 = group1.getTags().iterator();
		while (groupTagIter1.hasNext()) {
			tagMultiplicator = 1;
			Iterator<Tag> groupTagIter2 = group2.getTags().iterator();
			String Keyword3 = groupTagIter1.next().getKeyword();

			while (groupTagIter2.hasNext()) {

				String Keyword4 = groupTagIter2.next().getKeyword();
				if (Keyword3.equals(Keyword4)) {
					score += ScoreForSameTagOfGroup * tagMultiplicator;
					tagMultiplicator = tagMultiplicator
							* groupTagMultiplikationFactor;
				}
			}
		}

		return score;

	}

	/* (non-Javadoc)
	 * @see net.groupme.similarityComputer.SimilarityComputer#printSettings()
	 */
	public String printSettings() {
		return "{ class : " + SimCom.class.getCanonicalName() + ", " +
				" ScoreForSameResourceInGroup : " + ScoreForSameResourceInGroup + ", " +
				" ScoreForSameTagOfDifferentResource : " + ScoreForSameTagOfDifferentResource + ", " +
				" ScoreForSameTagOfGroup : " + ScoreForSameTagOfGroup + ", " +
				" ScoreForSameTagOfResource : " + ScoreForSameTagOfResource + ", " +
				" ScoreForSameResourceInGroup : " + groupTagMultiplikationFactor + ", " +
				" ScoreForSameResourceInGroup : " + resourceMultiplikationFactor + ", " +
				" ScoreForSameResourceInGroup : " + resourceTagDiffernetMultiplikationFactor + ", " +
				" ScoreForSameResourceInGroup : " + resourceTagMultiplikationFactor +
				" }";
	}

}